#include <middleware/gm_api/skfapi.h>
#include <middleware/gm_api/skfapi_ex.h>
#include <middleware/mk_lib/mk_auto_mutex.h>
#include <middleware/mk_lib/mk_utility.h>
#include <middleware/apdu/apdu.lib/apdu_lib_key_mgr.h>
#include <middleware/apdu/apdu.lib/apdu_lib_rsa_mgr.h>
#include <middleware/apdu/apdu.lib/apdu_lib_ecc_mgr.h>
#include <middleware/apdu/apdu.lib/apdu_lib_cryption_mgr.h>
#include <middleware/apdu/apdu.lib/apdu_lib_container_mgr.h>
#include <middleware/apdu/apdu.lib/apdu_lib_pin_mgr.h>
#include <middleware/mk_lib/mk_logger.h>
#include "../gm_data_mgr/gm_sc_mgr.h"
#include "gm_global.h"
#include "gm_defs.h"
#include <middleware/os/os_thread.h>


ULONG DEVAPI SKF_GenExtRSAKey(DEVHANDLE hDev, ULONG ulBitsLen, RSAPRIVATEKEYBLOB *pBlob)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_GenExtRSAKey(), ulBitsLen=%ld", ulBitsLen);
	ULONG lRslt = SAR_OK;
	int pri_size = sizeof(RSAPRIVATEKEYBLOB);
	unsigned char * pPriBlob = (unsigned char*)pBlob;
	unsigned char pri_blob[2048] = {0};
	int pri_blob_len = sizeof(pri_blob);

	unsigned char pub_blob[512] = {0};
	int pub_blob_len = sizeof(pub_blob);
	
	gm_sc_dev		*pdev = gm_sc_mgr::get_dev_ptr()->get_dev_by_handle(hDev);
	TRACE_ASSERT(pdev);

	lRslt = app_gen_ext_rsa_keypair(pdev->get_apdu_handle(), ulBitsLen, pri_blob, &pri_blob_len);
	ERROR_THROW(lRslt);

	lRslt = app_export_ext_rsa_pubkey(pdev->get_apdu_handle(), pub_blob, &pub_blob_len);
	ERROR_THROW(lRslt);
	
	memcpy(pPriBlob, pub_blob, pub_blob_len);
	memcpy(pPriBlob + pub_blob_len, pri_blob, pri_blob_len);
	pBlob->AlgID = SGD_RSA;
	mk_utility::reverse_bytes(&pBlob->BitLen, 4);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_GenExtRSAKey(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_ExtRSAPriKeyOperation(DEVHANDLE hDev, RSAPRIVATEKEYBLOB* pRSAPriKeyBlob,BYTE* pbInput, ULONG ulInputLen, 
									   BYTE* pbOutput, ULONG* pulOutputLen)
{
	MK_AUTO_MUTEX
		DBG_LOGMSG("enter SKF_ExtRSAPriKeyOperation(), ulInputLen=%ld", ulInputLen);
	ULONG lRslt = SAR_OK;
	unsigned char * priBlob= (unsigned char*)pRSAPriKeyBlob;
	
	gm_sc_dev		*pdev = gm_sc_mgr::get_dev_ptr()->get_dev_by_handle(hDev);
	TRACE_ASSERT(pdev);
	//import 1st part - pub key
	lRslt = app_import_ext_rsa_keypair_to_ram(pdev->get_apdu_handle(), 0, priBlob, sizeof(RSAPUBLICKEYBLOB));
	ERROR_THROW(lRslt);

	//import last part - pri key
	lRslt = app_import_ext_rsa_keypair_to_ram(pdev->get_apdu_handle(), 1, priBlob + sizeof(RSAPUBLICKEYBLOB), 
					sizeof(RSAPRIVATEKEYBLOB) - sizeof(RSAPUBLICKEYBLOB));
	ERROR_THROW(lRslt);

	//private operation 
	lRslt = app_ram_rsa_private(pdev->get_apdu_handle(), pbInput, ulInputLen, pbOutput, (int*)pulOutputLen);
	ERROR_THROW(lRslt);
	
END_OF_FUN:
	DBG_LOGMSG("leave SKF_ExtRSAPriKeyOperation(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_GenRSAKeyPairEx (HCONTAINER hContainer, BYTE bSignFlag, ULONG ulBitsLen, RSAPUBLICKEYBLOB *pBlob)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_GenRSAKeyPairEx(), bSignFlag=%ld", bSignFlag);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pbPublic[ECC_MODULUS_BITS_LEN * 2] = {0};
	int				nLen = ECC_MODULUS_BITS_LEN * 2;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		lRslt = SAR_USER_NOT_LOGGED_IN;
		goto END_OF_FUN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	lRslt = app_gen_rsa_keypair_ex(hdev, app_id, pContainer->id(), ulBitsLen, bSignFlag, pbPublic, nLen);
	ERROR_THROW_APDU(lRslt)

	pBlob->AlgID = SGD_RSA;
	pBlob->BitLen = ulBitsLen;
	memcpy(pBlob->Modulus+MAX_RSA_MODULUS_LEN-ulBitsLen/8, pbPublic, ulBitsLen/8);
	memcpy(pBlob->PublicExponent, pbPublic+ulBitsLen/8, MAX_RSA_EXPONENT_LEN);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_GenRSAKeyPairEx(), ret=%08x sw=%08x", lRslt, get_last_sw_err());
	return lRslt;
}

ULONG DEVAPI SKF_ImportExtRSAKeyPair(HCONTAINER hContainer, BYTE bSignFlag, RSAPRIVATEKEYBLOB *pBlob)
{

	MK_AUTO_MUTEX
	DBG_LOGBUFFER((BYTE *)pBlob, sizeof(RSAPRIVATEKEYBLOB), "enter SKF_ImportExtRSAKeyPair(), bSignFlag=%ld", bSignFlag);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pRsa[1024] = {0};
	ULONG			ulRsalen = 1024;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		return SAR_USER_NOT_LOGGED_IN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();


	lRslt = app_import_ext_rsa_keypair(hdev, app_id, pContainer->id(), bSignFlag, (BYTE *)pBlob, sizeof(RSAPRIVATEKEYBLOB));
	ERROR_THROW_APDU(lRslt)

END_OF_FUN:
	DBG_LOGMSG("leave SKF_ImportExtRSAKeyPair(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_RSAPublicOperation(HCONTAINER hContainer, BYTE bSignFlag, BYTE * pbInput, ULONG ulInputLen, BYTE * pbOutput, ULONG * pulOutputLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSAPublicOperation(), bSignFlag=%ld, ulInputLen=%ld", bSignFlag, ulInputLen);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pbdata[ECC_MODULUS_BITS_LEN * 2] = {0};
	int				nLen = ECC_MODULUS_BITS_LEN * 2;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	lRslt = app_rsa_public(hdev, app_id, pContainer->id(), bSignFlag, pbInput, ulInputLen,  pbdata, &nLen);
	ERROR_THROW_APDU(lRslt)

	TRACE_ASSERT_LEN(*pulOutputLen, nLen)

	memcpy(pbOutput, pbdata, nLen);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSAPublicOperation(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_RSAPrivateOperation(HCONTAINER hContainer, BYTE bSignFlag, BYTE * pbInput, ULONG ulInputLen, BYTE * pbOutput, ULONG * pulOutputLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSAPrivateOperation(), bSignFlag=%ld, ulInputLen=%ld", bSignFlag, ulInputLen);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pbdata[ECC_MODULUS_BITS_LEN * 2] = {0};
	int				nLen = ECC_MODULUS_BITS_LEN * 2;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		return SAR_USER_NOT_LOGGED_IN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	lRslt = app_rsa_private(hdev, app_id, pContainer->id(), bSignFlag, pbInput, ulInputLen,  pbdata, &nLen);
	ERROR_THROW_APDU(lRslt)

	TRACE_ASSERT_LEN(*pulOutputLen, nLen)
	memcpy(pbOutput, pbdata, nLen);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSAPrivateOperation(), ret=%08x", lRslt);
	return lRslt;
}


ULONG DEVAPI SKF_ExtRSAPubKeyOperation (DEVHANDLE hDev, RSAPUBLICKEYBLOB* pRSAPubKeyBlob,BYTE* pbInput, ULONG ulInputLen, BYTE* pbOutput, ULONG* pulOutputLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_ExtRSAPubKeyOperation(), ulInputLen=%ld", ulInputLen);

	ULONG			lRslt = SAR_OK;
	BYTE			pbdata[ECC_MODULUS_BITS_LEN * 2] = {0};
	int				nLen = ECC_MODULUS_BITS_LEN * 2;
	BYTE			rsa[512] = {0};
	int				pos = 0;
	gm_sc_dev *pdev = gm_sc_mgr::get_dev_ptr()->get_dev_by_handle(hDev);
	TRACE_ASSERT(pdev);

	TRACE_ASSERT(ulInputLen == 128 || ulInputLen == 256)

	if(pbOutput == NULL)
	{
		*pulOutputLen = ulInputLen;
		goto END_OF_FUN;
	}


	memcpy(rsa, &pRSAPubKeyBlob->BitLen, sizeof(pRSAPubKeyBlob->BitLen));
	mk_utility::reverse_bytes(rsa, sizeof(pRSAPubKeyBlob->BitLen));
	pos += sizeof(pRSAPubKeyBlob->BitLen);
	memcpy(rsa + pos, pRSAPubKeyBlob->Modulus + MAX_RSA_MODULUS_LEN - (pRSAPubKeyBlob->BitLen + 7)/8 , (pRSAPubKeyBlob->BitLen + 7)/8);
	pos += (pRSAPubKeyBlob->BitLen + 7)/8;
	memcpy(rsa + pos, pRSAPubKeyBlob->PublicExponent, 4);
	pos += 4;

	lRslt = app_rsa_ext_rsa_pubkey_operation(pdev->get_apdu_handle(), rsa, pos, pbInput, ulInputLen, pbdata, &nLen);
	ERROR_THROW_APDU(lRslt)

	TRACE_ASSERT_LEN(*pulOutputLen, nLen)

	memcpy(pbOutput, pbdata, nLen);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_ExtRSAPubKeyOperation(), ret=%08x", lRslt);
	return lRslt;
}


ULONG DEVAPI SKF_RSASignEx(HCONTAINER hContainer, BYTE bSignFlag, ULONG ulHashAlgID, BYTE *pbData, ULONG  ulDataLen, BYTE *pbSignature, ULONG *pulSignLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSASignEx(), ulDataLen=%ld", ulDataLen);

	ULONG			lRslt = SAR_OK;
	int				sig_len = RSA_KEYPAIR_BITS_2048;
	unsigned char	szSignature[RSA_KEYPAIR_BITS_2048] = {0};
	HANDLE			hdev;
	ULONG			app_id;
	gm_sc_cont		*pcont = (gm_sc_cont*)hContainer;


	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}
	TRACE_ASSERT(hContainer && (ulDataLen < MAX_RSA_MODULUS_LEN-11));

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	ulHashAlgID = gm_sc_key::get_dev_alg_id(ulHashAlgID);

	lRslt = app_rsa_sign_ex(hdev, app_id, pContainer->id(), bSignFlag, ulHashAlgID, pbData, ulDataLen,
						szSignature, &sig_len);
	ERROR_THROW_APDU(lRslt)

	if(pbSignature == NULL)
	{
		*pulSignLen = sig_len;
		goto END_OF_FUN;
	}

	TRACE_ASSERT_LEN(*pulSignLen, sig_len)
	*pulSignLen = sig_len;
	memcpy(pbSignature, szSignature, sig_len);

END_OF_FUN:
		DBG_LOGMSG("leave SKF_RSASignEx(), ret=%08x", lRslt);
		return lRslt;
}

ULONG DEVAPI SKF_RSAVerifyEx(HCONTAINER hContainer, BYTE bSignFlag, ULONG ulHashAlgID, BYTE *pbData, ULONG  ulDataLen, BYTE *pbSignature, ULONG ulSignLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSAVerifyEx(), ulDataLen=%ld", ulDataLen);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}
	TRACE_ASSERT(pbData != NULL && pbSignature != NULL)

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	ulHashAlgID = gm_sc_key::get_dev_alg_id(ulHashAlgID);
	
	lRslt = app_rsa_verify_ex(hdev, app_id, pContainer->id(), bSignFlag, ulHashAlgID, pbData, ulDataLen, pbSignature, ulSignLen);
	ERROR_THROW_APDU(lRslt)

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSAVerifyEx(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_DeleteKeyPair(HCONTAINER hContainer, BYTE bSignFlag)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_DeleteKeyPair(), bSignFlag=%ld", bSignFlag);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	lRslt = app_delete_keypair(hdev, app_id, pContainer->id(), bSignFlag);
	ERROR_THROW_APDU(lRslt)

END_OF_FUN:
	DBG_LOGMSG("leave SKF_DeleteKeyPair(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_DeleteCertificate(HCONTAINER hContainer, BYTE bSignFlag)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_DeleteKeyPair(), bSignFlag=%ld", bSignFlag);
	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();


	lRslt = app_delete_certificate(hdev, app_id, pContainer->id(), bSignFlag);
	ERROR_THROW_APDU(lRslt)

END_OF_FUN:
	DBG_LOGMSG("leave SKF_DeleteKeyPair(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_RSAEncrypt(HCONTAINER hContainer, BYTE bSignFlag, BYTE * pbInput, ULONG ulInputLen, BYTE * pbOutput, ULONG * pulOutputLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSAEncrypt(), ulInputLen=%ld", ulInputLen);

	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pdata[1024] = {0};
	ULONG			data_len = 1024;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	lRslt = app_rsa_encrypt_pkcs1(hdev, app_id, pContainer->id(), bSignFlag, pbInput, ulInputLen, pdata, (int *)&data_len);
	ERROR_THROW_APDU(lRslt)

	if(pbOutput == NULL)
	{
		*pulOutputLen = data_len;
		goto END_OF_FUN;
	}
	TRACE_ASSERT_LEN(*pulOutputLen, data_len)

	memcpy(pbOutput, pdata, data_len);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSAEncrypt(), ret=%08x", lRslt);
	return lRslt;
}


ULONG DEVAPI SKF_RSADecrypt(HCONTAINER hContainer, BYTE bSignFlag, BYTE * pbInput, ULONG ulInputLen, BYTE * pbOutput, ULONG * pulOutputLen)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSADecrypt(), ulInputLen=%ld", ulInputLen);

	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pdata[1024] = {0};
	ULONG			data_len = 1024;

	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		lRslt = SAR_USER_NOT_LOGGED_IN;
		goto END_OF_FUN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();
	lRslt = app_rsa_decrypt_pkcs1(hdev, app_id, pContainer->id(), bSignFlag, pbInput, ulInputLen, pdata, (int *)&data_len);
	ERROR_THROW_APDU(lRslt)

	if(pbOutput == NULL)
	{
		*pulOutputLen = data_len;
		goto END_OF_FUN;
	}
	TRACE_ASSERT_LEN(*pulOutputLen, data_len)

	memcpy(pbOutput, pdata, data_len);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSADecrypt(), ret=%08x", lRslt);
	return lRslt;
}


////////////////
ULONG DEVAPI SKF_ExtRSAVerify (DEVHANDLE hDev, RSAPUBLICKEYBLOB* pRSAPubKeyBlob, ULONG hashAlgo,
							   BYTE *pbData, ULONG  ulDataLen, BYTE *pbSignature, ULONG ulSignLen)
{
	MK_AUTO_MUTEX
		DBG_LOGMSG("enter SKF_ExtRSAVerify(), ulSignLen=%ld, sizeof(ULONG) = %d", ulSignLen, sizeof(ULONG));
	ULONG			lRslt = SAR_OK;
	ULONG			ulPubKeyBloblen;
	BYTE bTemp[RSA_KEYPAIR_BITS_1024] = {0};
	gm_sc_dev *pdev = gm_sc_mgr::get_dev_ptr()->get_dev_by_handle(hDev);

	ULONG ulAlgID = gm_sc_key::get_dev_alg_id(hashAlgo);

	TRACE_ASSERT(hDev)
		TRACE_ASSERT(pRSAPubKeyBlob != NULL && pbData != NULL && pbSignature != NULL)
		TRACE_ASSERT(ulSignLen == MAX_RSA_MODULUS_LEN || ulSignLen == MAX_RSA_MODULUS_LEN/2)

		ulPubKeyBloblen = pRSAPubKeyBlob->BitLen;
	if(pRSAPubKeyBlob->BitLen == RSA_KEYPAIR_BITS_1024 || pRSAPubKeyBlob->BitLen == RSA_KEYPAIR_BITS_2048)
	{
		mk_utility::reverse_bytes(&ulPubKeyBloblen, 4);
	}


	memcpy(&bTemp[0], &ulPubKeyBloblen, 4);
	memcpy(&bTemp[4], pRSAPubKeyBlob->Modulus+MAX_RSA_MODULUS_LEN-pRSAPubKeyBlob->BitLen/8, pRSAPubKeyBlob->BitLen/8);
	memcpy(&bTemp[4+pRSAPubKeyBlob->BitLen/8], pRSAPubKeyBlob->PublicExponent, 4);

	DBG_LOGBUFFER(bTemp, sizeof(RSAPUBLICKEYBLOB), "RSAPUBLICKEYBLOB:");

	lRslt = app_rsa_verify(pdev->get_apdu_handle(), 2, ulAlgID, 
		bTemp, 8+(pRSAPubKeyBlob->BitLen/8), pbData, ulDataLen, pbSignature, ulSignLen);

	ERROR_THROW_APDU(lRslt)

END_OF_FUN:
	DBG_LOGMSG("leave SKF_ExtRSAVerify(), ret=%08x", lRslt);
	return lRslt;
}


ULONG DEVAPI SKF_ExtRSAEncrypt(DEVHANDLE hDev, RSAPUBLICKEYBLOB* pRSAPubKeyBlob,BYTE* pbInput, ULONG ulInputLen, 
							   BYTE* pbOutput, ULONG* pulOutputLen)
{

	MK_AUTO_MUTEX
		DBG_LOGMSG("enter SKF_ExtRSAEncrypt(), ulInputLen=%ld", ulInputLen);

	ULONG			lRslt = SAR_OK;
	BYTE			pbdata[ECC_MODULUS_BITS_LEN * 2] = {0};
	int				nLen = ECC_MODULUS_BITS_LEN * 2;
	BYTE			rsa[512] = {0};
	int				pos = 0;
	gm_sc_dev *pdev = gm_sc_mgr::get_dev_ptr()->get_dev_by_handle(hDev);

	memcpy(rsa, &pRSAPubKeyBlob->BitLen, sizeof(pRSAPubKeyBlob->BitLen));
	mk_utility::reverse_bytes(rsa, sizeof(pRSAPubKeyBlob->BitLen));
	pos += sizeof(pRSAPubKeyBlob->BitLen);
	memcpy(rsa + pos, pRSAPubKeyBlob->Modulus + MAX_RSA_MODULUS_LEN - (pRSAPubKeyBlob->BitLen + 7)/8 , (pRSAPubKeyBlob->BitLen + 7)/8);
	pos += (pRSAPubKeyBlob->BitLen + 7)/8;
	memcpy(rsa + pos, pRSAPubKeyBlob->PublicExponent, 4);
	pos += 4;

	lRslt = app_rsa_ext_rsa_encrypt(pdev->get_apdu_handle(), rsa, pos, pbInput, ulInputLen, pbdata, &nLen);
	ERROR_THROW_APDU(lRslt)

		TRACE_ASSERT_LEN(*pulOutputLen, nLen)

		memcpy(pbOutput, pbdata, nLen);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_ExtRSAEncrypt(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_RSASignDataInteractive(HCONTAINER hContainer, BYTE bSignFlag, ULONG ulHashAlgID, BYTE *pbData, ULONG  ulDataLen, ULONG timeOut,
										BYTE *pbSignature, ULONG *pulSignLen)
{
	
	DBG_LOGMSG("enter SKF_RSASignDataInteractive(), ulInputLen=%ld", ulDataLen);

	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	BYTE			pdata[1024] = {0};
	ULONG			data_len = 1024;
	ULONG			t = timeOut + 5;
	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		lRslt = SAR_USER_NOT_LOGGED_IN;
		goto END_OF_FUN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	ulHashAlgID = gm_sc_key::get_dev_alg_id(ulHashAlgID);
	
	app_rsa_sign_data_interactive_cancel(hdev, app_id, pContainer->id(), bSignFlag, ulHashAlgID);
	while(t-- > 0)
	{
		MK_AUTO_MUTEX
		lRslt = app_rsa_sign_data_interactive(hdev, app_id, pContainer->id(), bSignFlag, ulHashAlgID, timeOut, pbData, ulDataLen, pdata, (int *)&data_len);
		if(lRslt == SAR_OK)
		{		
			break;
		}

		if(get_last_sw() != 0x6F01)//waiting
		{
			ERROR_THROW_APDU(lRslt);
		}

		thread_sleep(1000);
	}
	ERROR_THROW_APDU(lRslt)

	if(pbSignature == NULL)
	{
		*pulSignLen = data_len;
		goto END_OF_FUN;
	}
	TRACE_ASSERT_LEN(*pulSignLen, data_len)

	memcpy(pbSignature, pdata, data_len);

END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSASignDataInteractive(), ret=%08x", lRslt);
	return lRslt;
}

ULONG DEVAPI SKF_RSASignDataInteractiveCancel(HCONTAINER hContainer, BYTE bSignFlag, ULONG ulHashAlgID)
{
	MK_AUTO_MUTEX
	DBG_LOGMSG("enter SKF_RSASignDataInteractiveCancel(), hContainer=%ld", hContainer);

	ULONG			lRslt = SAR_OK;
	HANDLE			hdev;
	ULONG			app_id;
	gm_sc_dev * pDev = NULL;
	gm_sc_app * pApp = NULL;

	gm_sc_cont * pContainer = gm_sc_mgr::get_dev_ptr()->find_container(hContainer, pDev, pApp);
	if(!pContainer)
	{
		lRslt = SAR_INVALIDHANDLEERR;
		ERROR_THROW(lRslt);
	}

	if(!pApp->IsVerify())
	{
		lRslt = SAR_USER_NOT_LOGGED_IN;
		goto END_OF_FUN;
	}

	hdev = pDev->get_apdu_handle();
	app_id = pApp->id();

	ulHashAlgID = gm_sc_key::get_dev_alg_id(ulHashAlgID);

	lRslt = app_rsa_sign_data_interactive_cancel(hdev, app_id, pContainer->id(), bSignFlag, ulHashAlgID);
	ERROR_THROW_APDU(lRslt)


END_OF_FUN:
	DBG_LOGMSG("leave SKF_RSASignDataInteractiveCancel(), ret=%08x", lRslt);
	return lRslt;
}
